<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<!--

`<core-transition-css>` implements CSS transitions as `<core-transition>` objects so they can be
reused in a pluggable transition system such as in `<core-overlay>`. Currently this class has
some specific support to animate an element from and to the viewport such as a dialog, but you
can override it for different effects.

Example:

my-css-transition.html:

    <polymer-element name="my-css-transition" extends="core-transition-css">
    <template>
        <style>
            :host(.my-transition) {
                opacity: 0;
                transition: transform 1s ease-out, opacity 1s ease-out;
            }
            :host(.my-transition.my-opened) {
                opacity: 1;
                transform: none;
            }
            :host(.my-transition-top) {
                transform: translateY(-100vh);
            }
            :host(.my-transition-bottom) {
                transform: translateY(100vh);
            }
        </style>
    </template>
    <script>
      Polymer({
        baseClass: 'my-transition',
        openedClass: 'my-opened'
      });
    </script>
    </polymer-element>

    <my-css-transition id="my-transition-top" transitionType="top"></my-css-transition>
    <my-css-transition id="my-transition-bottom" transitionType="bottom"></my-css-transition>

my-css-transition-demo.html

    <link href="components/core-meta/core-meta.html" rel="import">
    <link href="my-css-transition.html">

    <div id="animate-me"></div>

    <script>
        // Get the core-transition
        var meta = document.createElement('core-meta');
        meta.type = 'transition';
        var transition1 = meta.byId('my-transition-top');

        // Set up the animation
        var animated = document.getElementById('animate-me');
        transition1.setup(animated);
        transition1.go(animated, {opened: true});
    </script>

The first element in the template of a `<core-transition-css>` object should be a stylesheet. It
will be injected to the scope of the animated node in the `setup` function. The node is initially
invisible with `opacity: 0`, and you can transition it to an "opened" state by passing
`{opened: true}` to the `go` function.

All nodes being animated will get the class `my-transition` added in the `setup` function.
Additionally, the class `my-transition-<transitionType>` will be applied. You can use the
`transitionType` attribute to implement several different behaviors with the same
`<core-transition-css>` object. In the above example, `<my-css-transition>` implements both
sliding the node from the top of the viewport and from the bottom of the viewport.

Available transitions
---------------------

`<core-transition-css>` includes several commonly used transitions.

`core-transition-fade`: Animates from `opacity: 0` to `opacity: 1` when it opens.

`core-transition-center`: Zooms the node into the final size.

`core-transition-top`: Slides the node into the final position from the top.

`core-transition-bottom`: Slides the node into the final position from the bottom.

`core-transition-left`: Slides the node into the final position from the left.

`core-transition-right`: Slides the node into the final position from the right.

@group Polymer Core Elements
@element core-transition-css
@extends core-transition
@status beta
@homepage github.io
-->

<link rel="import" href="core-transition.html">

<polymer-element name="core-transition-css" extends="core-transition" attributes="transitionType">
<template>
  <link no-shim rel="stylesheet" href="core-transition-overlay.css">
</template>
<script>

  Polymer('core-transition-css', {
    
    /**
     * The class that will be applied to all animated nodes.
     *
     * @attribute baseClass
     * @type string
     * @default "core-transition"
     */
    baseClass: 'core-transition',

    /**
     * The class that will be applied to nodes in the opened state.
     *
     * @attribute openedClass
     * @type string
     * @default "core-opened"
     */
    openedClass: 'core-opened',

    /**
     * The class that will be applied to nodes in the closed state.
     *
     * @attribute closedClass
     * @type string
     * @default "core-closed"
     */
    closedClass: 'core-closed',

    /**
     * Event to listen to for animation completion.
     *
     * @attribute completeEventName
     * @type string
     * @default "transitionEnd"
     */
    completeEventName: 'transitionend',

    publish: {
      /**
       * A secondary configuration attribute for the animation. The class
       * `<baseClass>-<transitionType` is applied to the animated node during
       * `setup`.
       *
       * @attribute transitionType
       * @type string
       */
      transitionType: null
    },

    registerCallback: function(element) {
      this.transitionStyle = element.templateContent().firstElementChild;
    },

    // template is just for loading styles, we don't need a shadowRoot
    fetchTemplate: function() {
      return null;
    },

    go: function(node, state) {
      if (state.opened !== undefined) {
        this.transitionOpened(node, state.opened);
      }
    },

    setup: function(node) {
      if (!node._hasTransitionStyle) {
        if (!node.shadowRoot) {
          node.createShadowRoot().innerHTML = '<content></content>';
        }
        this.installScopeStyle(this.transitionStyle, 'transition',
            node.shadowRoot);
        node._hasTransitionStyle = true;
      }
      node.classList.add(this.baseClass);
      if (this.transitionType) {
        node.classList.add(this.baseClass + '-' + this.transitionType);
      }
    },

    teardown: function(node) {
      node.classList.remove(this.baseClass);
      if (this.transitionType) {
        node.classList.remove(this.baseClass + '-' + this.transitionType);
      }
    },

    transitionOpened: function(node, opened) {
      this.listenOnce(node, this.completeEventName, function() {
        node.classList.toggle(this.revealedClass, opened);
        if (!opened) {
          node.classList.remove(this.closedClass);
        }
        this.complete(node);
      });
      node.classList.toggle(this.openedClass, opened);
      node.classList.toggle(this.closedClass, !opened);
    }

  });
</script>
</polymer-element>

<core-transition-css id="core-transition-fade"></core-transition-css>
<core-transition-css id="core-transition-center" transitionType="center"></core-transition-css>
<core-transition-css id="core-transition-top" transitionType="top"></core-transition-css>
<core-transition-css id="core-transition-bottom" transitionType="bottom"></core-transition-css>
<core-transition-css id="core-transition-left" transitionType="left"></core-transition-css>
<core-transition-css id="core-transition-right" transitionType="right"></core-transition-css>
